using System;
using System.Collections.Generic;

using MvcCms.Data;
using MvcCms.Service.Cache;
using MvcCms.Service.Validation;
using MvcCms.Service.Logging;
using Microsoft.Practices.ServiceLocation;
using MvcCms.Service.Code;

namespace MvcCms.Service.CMSCode
{
    public class PortalService : IPortalService
    {
        #region Constructors

        private readonly ICacheService _cacheService;
        private readonly ICmsService _cmsService;
        private readonly IPortalRepository _repository;
        private readonly IValidationDictionary _validationDictionary;

        public PortalService(IValidationDictionary validationDictionary,
                              IPortalRepository repository, ICacheService cacheService, ICmsService cmsService)
        {
            _validationDictionary = validationDictionary;
            _repository = repository;
            _cacheService = cacheService;
            _cmsService = cmsService;
        }

        #endregion

        #region Validation Methods

        private bool ValidatePortal(Portal portalToValidate)
        {
            if (portalToValidate.Name.Trim().Length == 0)
                _validationDictionary.AddError("Name", "Name is required.");
            if (portalToValidate.DisplayName.Trim().Length == 0)
                _validationDictionary.AddError("DisplayName", "Display Name is required.");
            if (portalToValidate.DefaultLanguage == null)
                _validationDictionary.AddError("LanguageID", "Default Language is required.");
            if (portalToValidate.SkinName.Trim().Length == 0)
                _validationDictionary.AddError("SkinName", "Skin Name is required.");
            if (portalToValidate.URLAuthority.Trim().Length == 0)
                _validationDictionary.AddError("URLAuthority", "URL Authority is required.");
            return _validationDictionary.IsValid;
        }

        private bool ValidatePortalResource(PortalResource portalresourceToValidate)
        {
            if (portalresourceToValidate.ResourceName.Trim().Length == 0)
                _validationDictionary.AddError("ResourceName", "Resource Name is required.");

            return _validationDictionary.IsValid;
        }

        #endregion

        #region Portal Methods

        public Portal GetPortal(int id)
        {
            return _repository.GetPortal(id);
        }
        public Portal GetPortal()
        {
            return _repository.GetPortal();
        }
        public bool CreateFeedBackItem(FeedBackItem feedBackItemToCreate)
        {
            // Database logic
            try
            {
                var portal = _repository.GetPortal(_cacheService.GetCurrentPortal().PortalID);
                feedBackItemToCreate.Portal = portal;
                _repository.CreateFeedBackItem(feedBackItemToCreate);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
            return true;
        }
        public Portal GetPortal(string urlAuthority)
        {
            return _repository.GetPortal(urlAuthority);
        }
        public Portal GetPortalByName(string portalName)
        {
            return _repository.GetPortalByName(portalName);
        }
        public bool CreatePortal(Portal portalToCreate)
        {
            // Validation logic
            if (!ValidatePortal(portalToCreate))
                return false;

            // Database logic
            try
            {
                _repository.CreatePortal(portalToCreate);
                _cacheService.ClearPortals();

                //create home category for portal
                // create published version page for new category
                var newcat = new ContentCategory
                {
                    AddedDate = DateTime.Now,
                    Editor = portalToCreate.PortalAdmin,
                    Title = "Home",
                    Path = "home",
                    Importance = 1,
                    Description = portalToCreate.Name + " Home page",
                    ShowInNav = true,
                    OnlyForMembers = false,
                    SinglePath = "home",
                    NumberOfParents = 0,
                    Portal = portalToCreate
                };
                return _cmsService.CreateContentCategory(newcat, portalToCreate);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
        }

        public IEnumerable<Portal> ListPortals()
        {
            return _repository.ListPortals();
        }

        public bool EditPortal(Portal portalToEdit)
        {
            // Validation logic
            if (!ValidatePortal(portalToEdit))
                return false;

            // Database logic
            try
            {
                _repository.EditPortal(portalToEdit);
                _cacheService.ClearPortals();
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
            return true;
        }

        public bool DeletePortal(Portal portalToDelete)
        {
            try
            {
                _repository.DeletePortal(portalToDelete);
                _cacheService.ClearPortals();
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
            return true;
        }

        #endregion

        #region Portal Resource Methods

        public PortalResource GetPortalResource(int id)
        {
            return _repository.GetPortalResource(id);
        }

        public PortalResourceType GetPortalResourceType(int id)
        {
            return _repository.GetPortalResourceType(id);
        }

        public PortalResource GetPortalResource(int portalid, int typeid)
        {
            return _repository.GetPortalResource(portalid, typeid);
        }

        public PortalResource GetPortalResource(int portalid, string typename)
        {
            return _repository.GetPortalResource(portalid, typename);
        }

        public IEnumerable<PortalResource> ListPortalResources()
        {
            return _repository.ListPortalResources(_cacheService.GetCurrentPortal());
        }

        public IEnumerable<PortalResourceType> ListPortalResourceTypes()
        {
            return _repository.ListPortalResourceTypes();
        }

        public bool CreatePortalResource(PortalResource portalresourceToCreate)
        {
            // Validation logic
            if (!ValidatePortalResource(portalresourceToCreate))
                return false;

            // Database logic
            try
            {
                _repository.CreatePortalResource(portalresourceToCreate);
                _cacheService.ClearPortals();
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
            return true;
        }

        public bool EditPortalResource(PortalResource portalresourceToEdit)
        {
            portalresourceToEdit.EditDate = DateTime.Now;
            // Validation logic
            if (!ValidatePortalResource(portalresourceToEdit))
                return false;

            // Database logic
            try
            {
                _repository.EditPortalResource(portalresourceToEdit);
                _cacheService.ClearPortals();
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
            return true;
        }

        #endregion

        #region Email Templates

        public bool CreateEmailTemplate(EmailTemplate emailTemplateToCreate)
        {
            try
            {
                var portalRepository = ServiceLocator.Current.GetInstance<IPortalRepository>();

                var portal = portalRepository.GetPortal(_cacheService.GetCurrentPortal().PortalID);
                emailTemplateToCreate.Portal = portal;
                // Database logic
                _repository.CreateEmailTemplate(emailTemplateToCreate);
                return true;
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
        }

        public IEnumerable<EmailTemplate> ListEmailTemplates()
        {
            return _repository.ListEmailTemplates(_cacheService.GetCurrentPortal().PortalID);
        }
        public bool EditEmailTemplate(EmailTemplate emailTemplateToEdit)
        {
            // Database logic
            try
            {
                _repository.EditEmailTemplate(emailTemplateToEdit);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
            return true;
        }
        #endregion
    }
}